package cn.b.sky.mes.pp.controller;

import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import cn.b.sky.mes.pp.model.ProductOrder;
import cn.b.sky.mes.pp.model.condition.ProductionOrderCondition;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.b.sky.mes.cm.model.Material;
import cn.b.sky.mes.cm.service.MaterialService;
import cn.b.sky.common.constants.SystemConstant;
import cn.b.sky.common.enums.DwzCallbackType;
import cn.b.sky.common.exception.ImeException;
import cn.b.sky.common.model.DWZResult;
import cn.b.sky.common.model.Page;
import cn.b.sky.user.SecurityContextUtil;
import cn.b.sky.user.controller.SecurityController;
import cn.b.sky.mes.cm.enums.ECodeEnums;
import cn.b.sky.mes.cm.enums.NumberRuleEnums;
import cn.b.sky.user.service.ECodeService;
import cn.b.sky.user.service.NumberRuleService;
import cn.b.sky.user.service.model.ECode;
import cn.b.sky.mes.pp.enums.PorderStatusCode;
import cn.b.sky.mes.pp.model.OrderType;
import cn.b.sky.mes.pp.model.ProductionOrder;
import cn.b.sky.mes.pp.service.OrderTypeService;
import cn.b.sky.mes.pp.service.ProductOrderService;

/**
 * 
 * <strong>Title : ProductOrderController.java<br>
 * </strong> <strong>Package : cn.b.sky.mes.pp.controller<br>
 * </strong> <strong>Description : </strong>产品订单控制器<br>
 * <strong>Create on : 2016-1-18 上午9:21:56<br>
 * </strong>
 * <p>
 * 
 * @author lidapeng<br>
 * @version <strong>v1.0.0</strong><br>
 * <br>
 *          <strong>修改历史:</strong><br>
 *          修改人 | 修改日期 | 修改描述<br>
 *          -------------------------------------------<br>
 * <br>
 * <br>
 */
@Controller
@RequestMapping("/productOrder/*")
@Slf4j
public class ProductOrderController extends SecurityController {
  @Resource
  ECodeService eCodeService;

  @Resource
  OrderTypeService orderTypeService;

  @Resource
  ProductOrderService productOrderService;

  @Resource
  NumberRuleService numberRuleService;

  @Resource
  MaterialService materialService;

  @RequestMapping("productOrder_list")
  public String productOrderList(String navTabId, @ModelAttribute("condition") ProductionOrderCondition condition,
      String productOrderNum, Model model) {
    condition.setSiteCode(this.getSiteCode());
    List<ECode> ecode = eCodeService.selectECodeList(ECodeEnums.PRODUCTORDER_TYPE.getCode(),
        SecurityContextUtil.getLanguageCode());
    // 订单状态
    List<OrderType> orderTypes = orderTypeService.getAllOrderTypes(this.getSiteCode());
    model.addAttribute("orderTypes", orderTypes);
    Page page = productOrderService.getProductOrdersByCondition(condition);
    model.addAttribute("page", page);
    model.addAttribute("orderStatusECode", ecode);
    model.addAttribute(NAVTABID, navTabId);
    return "pp/productOrder/productOrder_list";
  }

  /**
   * 
   * <strong>Title : addProductOrder<br>
   * </strong> <strong>Description : </strong>新增生产订单<br>
   * <strong>Create on : 2015-10-12 下午7:02:09<br>
   * </strong>
   * <p>
   * 
   * @param navTabId
   * @param model
   * @return String
   * @throws
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   *          <strong>修改历史:</strong><br>
   *          修改人 | 修改日期 | 修改描述<br>
   *          -------------------------------------------<br>
   * <br>
   * <br>
   */
  @RequestMapping("addProductOrder")
  public String addProductOrder(String navTabId, Model model) {
    /*
     * String productOrderNum = numberRuleService.selectNextNumber(
     * this.getSiteCode(), "ProductOrderEncodingRule");
     * model.addAttribute("productOrderNum", productOrderNum);
     */
    // 订单状态
    List<OrderType> orderTypes = orderTypeService.getAllUnlockedOrderTypes(this.getSiteCode());
    model.addAttribute("orderTypes", orderTypes);
    model.addAttribute(NAVTABID, navTabId);
    return "pp/productOrder/productOrder_add";
  }

  @RequestMapping("editProductOrder")
  public String editProductOrder(String navTabId, Model model, String productOrderNum) {
    if (!StringUtils.isBlank(productOrderNum)) {
      ProductOrder order = productOrderService.getProductOrderByPk(this.getSiteCode(), productOrderNum);
      model.addAttribute("productOrder", order);
      List<ECode> ecode = eCodeService.selectECodeList(ECodeEnums.PRODUCTORDER_TYPE.getCode(),
          SecurityContextUtil.getLanguageCode());
      // 订单状态
      List<OrderType> orderTypes = orderTypeService.getAllUnlockedOrderTypes(this.getSiteCode());
      model.addAttribute("orderTypes", orderTypes);
      model.addAttribute("orderStatusECode", ecode);
      model.addAttribute(NAVTABID, navTabId);
    }
    return "pp/productOrder/productOrder_edit";
  }

  @RequestMapping("viewProductOrder")
  public String viewProductOrder(String navTabId, Model model, String productOrderNum) {
    if (!StringUtils.isBlank(productOrderNum)) {
      ProductOrder order = productOrderService.getProductOrderByPk(this.getSiteCode(), productOrderNum);
      List<ECode> ProductOrderEcode = eCodeService.selectECodeList(ECodeEnums.PRODUCTORDER_TYPE.getCode(),
          SecurityContextUtil.getLanguageCode());
      List<ECode> productionEcode = eCodeService.selectECodeList(ECodeEnums.PRODUCTIONORDER_TYPE.getCode(),
          SecurityContextUtil.getLanguageCode());
      List<ProductionOrder> details = productOrderService.selectProductionOrdersByProductOrder(order.getSiteCode(),
          productOrderNum);
      model.addAttribute("orderStatusECode", ProductOrderEcode);
      model.addAttribute("productionEcode",productionEcode);
      model.addAttribute("productOrder", order);
      model.addAttribute("orderDetails", details);
    }
    return "pp/productOrder/productOrder_view";
  }

  @RequestMapping("saveProductOrder")
  @ResponseBody
  public DWZResult saveProductOrder(String navTabId, Model model, ProductOrder order) {
    if (order == null) {
      return ajaxError(getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(),
          "failedOp.M,productionOrderNum.C,isNull.M"));
    }
    if (order.getPlannedendDateTime().before(order.getPlannedstartDateTime())
         || order.getPlannedendDateTime().equals(order.getPlannedstartDateTime())) {
      return ajaxError(getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "planDateTimeError.M"));
    }
    Boolean isNew = false;
    if (StringUtils.isBlank(order.getProductOrderNum())) {
      String productOrderNum = numberRuleService.selectNextNumber(this.getSiteCode(),
          NumberRuleEnums.PRODUCTORDERNO.getValue());
      order.setProductOrderNum(productOrderNum);
      isNew = true;
    }

    this.setCreateInfo(order);
    // 创建
    order.setStatuseCode(PorderStatusCode.CREATE.getValue());
    if (isNew) {
      productOrderService.saveProductOrder(order);
    } else {
      productOrderService.modifyProductOrder(order);
    }
    return dialogAjaxDone(navTabId, null, null, null);
  }

  /**
   * 
   * <strong>Title : deleteProductionOrder<br></strong>
   * <strong>Description : </strong>删除产品订单<br> 
   * <strong>Create on : 2016-1-18 下午2:11:27<br></strong>
   * <p>
   * @param navTabId
   * @param model
   * @param productOrderNum
   * @return
   * DWZResult
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  @RequestMapping("deleteProductOrder")
  @ResponseBody
  public DWZResult deleteProductOrder(String navTabId, Model model, String productOrderNum) {
    if (StringUtils.isBlank(productOrderNum)) {
      return ajaxError(getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(),
          "failedOp.M,productionOrderNum.C,isNull.M"));
    } else {
      ProductOrder order = productOrderService.getProductOrderByPk(this.getSiteCode(), productOrderNum);
      if (order != null && !PorderStatusCode.CREATE.getValue().equals(order.getStatuseCode())) {
        ECode ecode = eCodeService.selectEcodeByECodeTypeAndLanguageCodeAndECode(order.getStatuseCode(),
            ECodeEnums.PRODUCTORDER_TYPE.getCode(), SecurityContextUtil.getLanguageCode());
        return ajaxError(this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "productionOrder_alread.M",
            ecode.geteCodeText()) + this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "notDelete.M"));
      }
      productOrderService.deleteProductOrderByPk(this.getSiteCode(), productOrderNum);
      return ajaxDone(null);
    }
  }

  /**
   * 
   * <strong>Title : checkedButtonEnable<br></strong>
   * <strong>Description : </strong>按钮前置事件<br> 
   * <strong>Create on : 2016-1-18 下午3:53:37<br></strong>
   * <p>
   * @param productOrderNum
   * @param type
   * @return
   * DWZResult
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  @RequestMapping("checkedButtonEnable")
  @ResponseBody
  public DWZResult checkedButtonEnable(String productOrderNum, String type) {
    ProductOrder order = productOrderService.getProductOrderByPk(this.getSiteCode(), productOrderNum);
    if (order == null) {
      return ajaxError(this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), SystemConstant.PARAMETERNULL));
    }
    
    ECode ecode = eCodeService.selectEcodeByECodeTypeAndLanguageCodeAndECode(order.getStatuseCode(),
        ECodeEnums.PRODUCTORDER_TYPE.getCode(), SecurityContextUtil.getLanguageCode());
    // 编辑
    if ("edit".equals(type) && !PorderStatusCode.CREATE.getValue().equals(order.getStatuseCode())) {
      return ajaxError(this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "productionOrder_alread.M",
          ecode.geteCodeText()) + this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "notEdit.M"));
    }
    // 分解
    if ("split".equals(type)) {
      if (!isCanSplitOrder(order)) {
        return ajaxError(this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "productionOrder_alread.M",
            ecode.geteCodeText()) + this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "notSplit.M"));
      }
      if (order.getPlannedQuantity() <= 0) {
        return ajaxError(this
            .getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "hasNot.M,plannedQuantity.C")
            + this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "notSplit.M"));
      }
      Material material = materialService.selectMaterial(this.getSiteCode(), order.getMaterialCode());
      if (material.getMakeFlag() == 0) {
        //非自制件不分解
        return ajaxError(this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "materialIsNotMake.M")
            + this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "notSplit.M"));
      }
    }
    return ajaxDone(null);
  }

  /**
   * 创建状态，和未分解完全状态可以再次分解
   */
  private boolean isCanSplitOrder(ProductOrder order) {
    if(PorderStatusCode.CREATE.getValue().equals(order.getStatuseCode())){
      return true;
    }
    if(PorderStatusCode.SPLIT_ORDER.getValue().equals(order.getStatuseCode()) 
        && order.getDecomposedQuantity().floatValue()
        < order.getPlannedQuantity().floatValue()){
      return true;
    }
    return false;
  }

  /**
   * 
   * <strong>Title : decomposeProductOrder<br></strong>
   * <strong>Description : </strong>分解<br> 
   * <strong>Create on : 2016-1-18 下午4:23:20<br></strong>
   * <p>
   * @return
   * String
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  @RequestMapping("decomposeProductOrder")
  public String decomposeProductOrder(String navTabId, Model model, String productOrderNum) {

    ProductOrder order = productOrderService.getProductOrderByPk(this.getSiteCode(), productOrderNum);
    String materialCode = order.getMaterialCode();
    if (!StringUtils.isBlank(materialCode)) {
      List<ProductionOrder> productionOrders = productOrderService.splitProductOrder(materialCode, this.getSiteCode(),
          order);
      model.addAttribute("productionOrders", productionOrders);

    } else {
      throw ImeException.newException("productOrderhasNotMaterial");
    }
    order.setDecompositionQuantity(order.getPlannedQuantity() - order.getDecomposedQuantity());
    model.addAttribute("productOrder", order);
    model.addAttribute(NAVTABID, navTabId);
    // 订单状态
    List<OrderType> orderTypes = orderTypeService.getAllUnlockedOrderTypes(this.getSiteCode());
    model.addAttribute("orderTypes", orderTypes);
    return "pp/productOrder/productOrder_decompose";
  }

  //分解保存
  @RequestMapping("saveProductionOrder")
  @ResponseBody
  public DWZResult saveProductionOrder(ProductOrder order, String navTabId, Model model) {
    if (order == null || StringUtils.isBlank(order.getProductOrderNum())) {
      return ajaxError(this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), SystemConstant.PARAMETERNULL));
    }
    if (order.getProductionOrder() == null || order.getProductionOrder().size() < 1) {
      return ajaxError(this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "order_notorderDetails.M"));
    }
    if (order.getDecompositionQuantity() <= 0) {
      return ajaxError(this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(),
          "decompositionQuantityGTzero.M"));
    }
    order.setSiteCode(this.getSiteCode());
    this.setCreateInfo(order);
    try {
      productOrderService.decompProductionOrders(order, order.getProductionOrder());
    } catch (ImeException e) {
      log.error("{}", e);
      return ajaxError(this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), e.getErrorCode(),
          e.getParameters()));
    }

    return dialogAjaxDone(navTabId, null, null, null);
  }

  @RequestMapping("closeProductOrder")
  @ResponseBody
  public DWZResult closeProductOrder(Model model, String navTabId, String productOrderNum, HttpServletRequest request) {
    ProductOrder order = productOrderService.getProductOrderByPk(this.getSiteCode(), productOrderNum);
    String statusCode = order.getStatuseCode();
    ECode ecode = eCodeService.selectEcodeByECodeTypeAndLanguageCodeAndECode(order.getStatuseCode(),
        ECodeEnums.PRODUCTORDER_TYPE.getCode(), SecurityContextUtil.getLanguageCode());
    if (PorderStatusCode.COMPLETE.getValue().equals(statusCode)) {
      return ajaxError(this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "productionOrder_alread.M",
          ecode.geteCodeText()) + this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "notClose.M"));
    }
    if (PorderStatusCode.CLOSE.getValue().equals(statusCode)) {
      return ajaxError(this.getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), "productionOrder_alread.M",
          ecode.geteCodeText()));
    }
    if (PorderStatusCode.CREATE.getValue().equals(order.getStatuseCode())) {
      productOrderService.closeProductOrder(this.getSiteCode(), productOrderNum, PorderStatusCode.CLOSE.getValue());
      return ajaxDone(null);
    } else if (PorderStatusCode.SPLIT_ORDER.getValue().equals(order.getStatuseCode())) {
      String forwardUrl = getForwardUrl(request) + "/productOrder/showProdeuctionOrder?navTabId=" + navTabId;
      forwardUrl += "&productOrderNum=" + productOrderNum;
      return navTabAjaxDone(null, null, DwzCallbackType.FORWARD, forwardUrl, null, null);
    }
    return ajaxDone(null);
  }

  @RequestMapping("showProdeuctionOrder")
  public String showProdeuctionOrder(String navTabId, Model model, String productOrderNum) {
    if (!StringUtils.isBlank(productOrderNum)) {
      List<ProductionOrder> details = productOrderService.selectProductionOrdersByProductOrder(this.getSiteCode(),
          productOrderNum);
      model.addAttribute("orderDetails", details);
      model.addAttribute("productOrderNum", productOrderNum);
    }
    model.addAttribute("productOrderNum", productOrderNum);
    model.addAttribute(NAVTABID, navTabId);
    List<ECode> ecode = eCodeService.selectECodeList(ECodeEnums.PRODUCTORDER_TYPE.getCode(),
        SecurityContextUtil.getLanguageCode());
    model.addAttribute("orderStatusECode", ecode);
    return "pp/productOrder/productionOrder_details";
  }

  @RequestMapping("closeSplitProductOrder")
  @ResponseBody
  public DWZResult closeSplitProductOrder(Model model, String navTabId, String productOrderNum,
      HttpServletRequest request) {
    if (!StringUtils.isBlank(productOrderNum)) {
      productOrderService.closeSplitProductOrder(productOrderNum, this.getSiteCode());
    }
    return dialogAjaxDone(navTabId, null, null, null);
  }
}
